跳到主要内容

CSS 中的盒模型

避免魔术值

在编程中不推荐魔术数值,因为往往难以解释一个魔术数值生效的原因。如果不理解这个数值是怎么来的,就不会知道在不同的情况下会产生什么样的结果。我的屏幕宽 1440px,在更小的视口下,侧边栏仍然会换行。虽然 CSS 中有时确实需要反复试验,但目的是为了得到更好的样式,而不是为了强行将一个元素填入一个位置。

替代魔术数值的一个方法是让浏览器帮忙计算。在本例中,因为加了内边距,两列的宽度总和超出了 3em,所以可以使用 calc() 函数减去这个值,得到刚好 100%的总和。比如设置侧边栏宽度为 calc(30% - 3em) 就能刚好并排放下两列,但是还有更好的解决办法。

调整盒模型

在 CSS 中可以使用 box-sizing 属性调整盒模型的行为。

box-sizing 属性可以被用来调整这些表现:

  • content-box 是默认值。如果你设置一个元素的宽为 100px,那么这个元素的内容区会有 100px 宽,并且任何边框和内边距的宽度都会被增加到最后绘制出来的元素宽度中。
  • border-box 告诉浏览器:你想要设置的边框和内边距的值是包含在 width 内的。也就是说,如果你将一个元素的 width 设为 100px,那么这 100px 会包含它的 border 和 padding,内容区的实际宽度是 width 减去 (border + padding) 的值。

大多数情况下,这使得我们更容易地设定一个元素的宽高。

.box {
box-sizing: content-box;
width: 100%;
border: solid #5B6DCD 10px;
padding: 5px;
}

.box {
box-sizing: border-box;
width: 100%;
border: solid #5B6DCD 10px;
padding: 5px;
}

给列之间加上间隔

通常在列之间加上一个小小的间隔会更好看

首先,给其中一列加上外边距,再调整元素的宽度,将多出来的空间减掉。从侧边栏的宽度中减掉了 1%,将其增加到外边距上。

控制溢出行为

当明确设置一个元素的高度时,内容可能会溢出容器。当内容在限定区域放不下,渲染到父元素外面时,就会发生这种现象。

用 overflow 属性可以控制溢出内容的行为,该属性支持以下 4 个值。

  • visible(默认值)所有内容可见,即使溢出容器边缘。
  • hidden 溢出容器内边距边缘的内容被裁剪,无法看见。
  • scroll 容器出现滚动条,用户可以通过滚动查看剩余内容。在一些操作系统上,会出现水平和垂直两种滚动条,即使所有内容都可见(不溢出)。不过,在这种情况下,滚动条不可滚动(置灰)。
  • auto 只有内容溢出时容器才会出现滚动条。

通常情况下,使用 auto 而不是 scroll,因为在大多数情况下,不希望滚动条一直出现。

请谨慎地使用滚动条。浏览器给网页最外层加上了滚动条,如果网页内部再嵌套滚动区域,用户就会很反感。如果用户使用鼠标滚轮滚动网页,当鼠标到达一个较小的滚动区域,滚轮就会停止滚动网页,转而滚动较小的区域

提示

水平方向的溢出怎么处理?

除了垂直溢出,内容也可能在水平方向溢出。一个典型的场景就是在一个很窄的容器中放一条很长的 URL。溢出的规则跟垂直方向上的一致。可以用 overflow-x 属性单独控制水平方向的溢出,或者用 overflow-y 控制垂直方向溢出。这些属性支持 overflow 的所有值,然而同时给 x 和 y 指定不同的值,往往会产生难以预料的结果。

垂直居中内容

CSS 中最简单的垂直居中方法是给容器相等的上下内边距,让容器和内容自行决定自己的高度。不管容器里的内容显示为行内、块级或者其他形式,这种方法都有效

但有时我们想给容器设置固定高度,或者无法使用内边距,因为想让容器内另一个子元素靠近容器的顶部或者底部。这种时候就需要使用 Flexbox 或者 Grid 布局。

外边距折叠

区块的上下外边距有时会合并(折叠)为单个边距,其大小为两个边距中的最大值(或如果它们相等,则仅为其中一个),这种行为称为 外边距折叠。注意:有设定浮动和绝对定位的元素不会发生外边距折叠。

有三种情况会形成外边距折叠:

相邻的兄弟元素:相邻的同级元素之间的外边距会被折叠(除非后面的元素需要清除之前的浮动)。

没有内容将父元素和后代元素分开:如果没有设定边框(border)、内边距(padding)、行级(inline)内容,也没有创建区块格式化上下文或间隙来分隔块级元素的上边距(margin-top)与其内一个或多个子代块级元素的上边距(margin-top);或者没有设定边框、内边距、行级内容、高度(height)或最小高度(min-height)来分隔块级元素的下边距(margin-bottom)与其内部的一个或多个后代后代块元素的下边距(margin-bottom),则会出现这些外边距的折叠,重叠部分最终会溢出到父代元素的外面。

空的区块:如果块级元素没有设定边框、内边距、行级内容、高度(height)、最小高度(min-height)来分隔块级元素的上边距(margin-top)及其下边距(margin-bottom),则会出现其上下外边距的折叠。

提示

注意:display 设置为 flex 或 grid 的容器中不会发生外边距折叠。

如下所示:

<p>这一段落的下边距与…</p>
<p>
… 这一段落的上边距被折叠了,在两者之间产生了一个
<code>1.2rem</code> 的边距。
</p>

<div>
这个父元素包含两个段落!
<p>
该段落与上面的文本之间有一个 <code>.4rem</code> 的边距。
</p>
<p>
我的下边距与我的父元素折叠,产生了一个 <code>2rem</code> 的边距。
</p>
</div>

<p>我在上面元素的下方 <code>2rem</code> 处。</p>

<style>
div {
margin: 2rem 0;
background: lavender;
}

p {
margin: 0.4rem 0 1.2rem 0;
background: yellow;
}
</style>

文字折叠

References

  • 《深入解析 CSS》